import cce_toolkit from '@/utils/cce_toolkit'

const {
	assets
} = require('@/config')

// ------ajax相关
const AJAXS = new Map(); //用于记录ajax请求态
uni.$on('ajaxComplete', function(url) {
	AJAXS.set(url, true)
})
// ------ajax相关

const checkSourceFn = function(assets) {
	// 校验数据类型
	if (cce_toolkit.verify_type(assets) !== 'Array') {
		throw new Error(`请检查索引的图片资源是否严格为数组类型`)
		return;
	}
	// 数组去重
	return cce_toolkit.removethesame_array(assets)
}

const downloadImgFn = function(path) {
	return new Promise((res, rej) => {
		const judgePath = path.includes('://') ? `${path}` : `${assets}${path}`;
		uni.getImageInfo({
			src: judgePath,
			success: function(imageInfo) {
				res(Object.assign(imageInfo, {
					originPath: path,
					serverPath: judgePath
				}))
			},
			fail: function(e) { //加载失败，则返回原始路径
				console.warn(e);
				res(Object.assign(e, {
					path: judgePath,
					originPath: path,
					serverPath: judgePath
				}))
			},
			complete: function(e) {
				// console.log(e)
			}
		})
	})
}

const limitNumFn = function(targetImg, _callback) {
	downloadImgFn(targetImg).then((res) => {
		_callback(res)
	})
}

const paddingAwait = function() {
	return new Promise(function(rev, rjt) {
		const setTimer = setTimeout(function() {
			clearTimeout(setTimer)
			rev();
		}, 500);
	})
}

const privateFn = Symbol('privateFn')

class TraversalAssets {
	constructor() {
		this._imglength = 0;
		this._imgObj = [];
		this._ajaxNum = [];
		this._lastPercent = 0;
		this._movieClip = [];
		// ...
	}

	addImgSheet(data) {
		data.asset = [];
		this._movieClip.push(data)
		return this._movieClip[this._movieClip.length - 1]['asset']
	}

	loadingImgSheet({
		imgPrefix = '',
		imgType = 'jpg',
		start = '0000',
		length,
		step = 1,
		mask = '0000',
		order,
	}, _callback) {
		
		// #ifdef MP-WEIXIN
			// 创建离屏 2D canvas 实例
			const canvas = wx.createOffscreenCanvas({
				type: '2d',
				width: 300,
				height: 150
			});
			// 获取 context。注意这里必须要与创建时的 type 一致
			const context = canvas.getContext('2d');
		// #endif
		
		const assetsBool = [];
		let originLength = length,
			originStart = parseInt(start),
			id = 0;

		do {
			// #ifdef MP-WEIXIN
				const image = canvas.createImage();
			// #endif
			// #ifdef H5
				const image = new Image();
			// #endif
			image.onload = () => {
				assetsBool[image.id] = image;
				const percent = parseInt((assetsBool.length / (Math.floor((length / step))) * 100).toFixed(0));
				this._movieClip[order]['asset'][image.id] = image;
				_callback(percent);
			};

			let realPath = cce_toolkit.prefixZero(originStart, mask.length);
			image.src = `${assets}${imgPrefix}${realPath}.${imgType}`;
			image.id = id;

			id++;
			originStart += step;
			originLength -= step;

		} while (originLength > 0);

	}

	startLoading(resources, _callback) {
		const _self = this;
		// 校验数据类型并去重
		resources = checkSourceFn(resources);

		// 过滤ajax类元素
		resources = resources.filter(function(value, index) {
			const bol = value.includes('ajax | ');
			if (bol) _self._ajaxNum.push(value.split('ajax | ')[1]);
			return bol ? false : true
		})

		const realPercentBOOL = Array(_self._movieClip.length).fill(0); //记录所有的百分比

		let targetArray = [...resources],
			loadingAssets = [],
			localAssest = [],
			oldPer = 0;

		let loadingLengthLimit = 9; //微信限制最大并发10条

		// #ifdef H5
			loadingLengthLimit = targetArray.length
		// #endif

		const _totalPercent = async function() {
			let ajaxReady = 0;

			for (let v of _self._ajaxNum) {
				if (AJAXS.get(v)) ajaxReady++;
			}

			const formatPer = Math.floor((ajaxReady + _self._imglength) / (_self._ajaxNum.length + resources
					.length) * 100)  || ((resources.length) ? 0 : 100);

			realPercentBOOL[0] = formatPer;

			const countPer = realPercentBOOL.reduce(function(total, num) {
				return total + num
			})

			const totalPer = countPer / realPercentBOOL.length

			_callback(totalPer.toFixed(0));

			// 图片资源会主动调用该函数，但ajax不会
			if (_self._imglength === resources.length && ajaxReady !== _self._ajaxNum.length) {
				await paddingAwait();
				_totalPercent()
				return;
			}

			if (Number(totalPer) === 100) {
				_self[privateFn](_self._imgObj, resources);
				return true;
			}
			return false;
		};

		const listenLengthFn = function() {
			if (!targetArray.length) {
				_totalPercent();
				return
			};
			while (loadingAssets.length < loadingLengthLimit && targetArray.length > 0) {
				let lastImg = targetArray.splice(targetArray.length - 1, 1)[0];
				loadingAssets.push(lastImg);
				limitNumFn(lastImg, function(res) {
					localAssest.push(res);
					const index = loadingAssets.indexOf(res['originPath']);
					loadingAssets.splice(index, 1);
					listenLengthFn();

					_self._imglength = localAssest.length;
					_self._imgObj = localAssest;
					_totalPercent();
				})
			}
		}

		if (this._movieClip) {
			for (let i = 0; i < this._movieClip.length; i++) {
				this._movieClip[i].order = i;
				this.loadingImgSheet(this._movieClip[i], (per, asset) => {
					realPercentBOOL[i + 1] = per;
					_totalPercent()
				});
			}
		}

		listenLengthFn()
	}

	onComplete() {
			// console.log("loading complete")
		}
		[privateFn](data, resources) { //私有方法，实例对象切勿调用
			const _self = this;
			const checkIsExist = getApp().globalData['cce_loaded_images']

			if (cce_toolkit.verify_type(checkIsExist) !== 'Map') {
				getApp().globalData['cce_loaded_images'] = new Map()
			}

			// 排序，保持与原loading数组对象顺序一致
			data.sort(function(a, b) {
				return resources.indexOf(a.originPath) - resources.indexOf(b.originPath)
			})

			for (let value of data) {
				getApp().globalData.cce_loaded_images.set(value['originPath'], value)
			}

			_self.onComplete(data)
		}
}

export default TraversalAssets
